<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>canvas get pixel color</title>
    <style type="text/css">
    #myCanvas {
        position: absolute;
        left: 50%;
        margin-left: -200px;
        top: 50%;
        margin-top: -200px;
        background: lightgray;
    }
    </style>
</head>

<body>
    <canvas id="myCanvas" width="400" height="400">
    </canvas>
    <script type="text/javascript">
    var canvas = document.getElementById("myCanvas")
    var ctx = canvas.getContext("2d");

    // 定义帧动画刷新率
    const raf = window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(callback) {
            window.setTimeout(callback, 1000 / 60);
        };
    var constRadii = 10;
    var targetColorCount = 0;
    var singleGraphArea = Math.PI * constRadii * constRadii; //circle
    // var singleGraphArea = 100;//square 

    console.log('singleGraphArea:', singleGraphArea)

    // drawCircle() 

    for (var i = 1; i <= 5; i++) {
        // drawSquare(pos = { x: 10 * i + 10, y: 10 * i + 10 })
        for (var j = 1; j <= 5; j++) {
        	drawCircle({ x: 20 * i, y: 20 * j })
        }
    }

    getAreaTargetGraph({ w: 200, h: 200 });

    //点击画布获取鼠标坐标
    canvas.addEventListener("mousedown", doMouseDown, false);

    function doMouseDown(e) {
        let mouseX = e.clientX - canvas.offsetLeft;
        let mouseY = e.clientY - canvas.offsetTop;
        console.log("mouse position on canvas:", mouseX, mouseY);

        let rgbaObj = getPixelRgba(mouseX, mouseY);
        console.log('return pixel rgba obj:', rgbaObj)
    }

    // 获取单位像素的rgba
    function getPixelRgba(x, y, size = { w: 1, h: 1 }) {
        let pixelRgba = ctx.getImageData(x, y, size.w, size.h).data;
        return {
            red: pixelRgba[0],
            green: pixelRgba[1],
            blue: pixelRgba[2],
            alpha: pixelRgba[3],
        };
    }

    // 获取区域 目标图形数量
    function getAreaTargetGraph(params = { x: 0, y: 0, w: 4, h: 4 }) { 
        let areaRgba = ctx.getImageData(params.x, params.y, params.w, params.h).data;
        console.log('areaRgba arraybuffer r+g+b+a totals:', areaRgba)
        let buf2arr = Array.prototype.slice.call(new Uint8ClampedArray(areaRgba));
        console.log('areaRgba array r+g+b+a totals:', buf2arr)
        let totalRgbaArr = sliceArrBy4(buf2arr); //total rgba arr
        let totalRgbaCount = totalRgbaArr.length; // total count   
        let foundRgbaCount = countReserveColor(totalRgbaArr, '0,0,0,0'); //found reserve rgba count

        // 计算最终识别出的目标图形数量
        let diffRgbaCount = totalRgbaCount - foundRgbaCount;
        let findTargetGraph = diffRgbaCount / singleGraphArea;
        console.log('find Target Graph:',  findTargetGraph)
        return Math.ceil(findTargetGraph)
    }

    function sliceArrBy4(arr) {
        let sArr = [];
        for (var i = 0; i < (arr.length) / 4; i++) {
            sArr.push(arr.slice(4 * i, 4 * i + 4).join(','))
        }

        console.log('sliced r,g,b,a arr:', sArr)
        return sArr;
    }

    function drawSquare(pos = { x: 0, y: 0 }, size = { w: 10, h: 10 }) {
        ctx.moveTo(pos.x, pos.y)
        ctx.lineTo(pos.x + size.w, pos.y)
        ctx.lineTo(pos.x + size.w, pos.y + size.h)
        ctx.lineTo(pos.x, pos.y + size.h)
        ctx.closePath();
        ctx.fillStyle = "rgba(255,0,0,1)";
        ctx.lineWidth = 1;
        ctx.fill();
    }

    function drawCircle(pos = { x: 200, y: 200 }) {
        ctx.beginPath();
        ctx.arc(pos.x, pos.y, constRadii, 0, 2 * Math.PI);
        ctx.fillStyle = "coral";
        ctx.fill();
    }

    // count background(the target's reserve color) rgba numbers
    function countReserveColor(areaArr, targetRgba = '255,0,0,255') {
        var count = 0;
        for (var i = 0; i < areaArr.length; i++) {
            if (areaArr[i] == targetRgba) {
                console.log('find reserve rgba ', targetRgba, ':', ++count)
            }
        }
        return count;
    }
    </script>
</body>

</html>